Dedicated SV copying code in place of Perl_sv_setsv_flags#23202
Merged
richardleach merged 13 commits intoPerl:bleadfrom Aug 23, 2025
Merged
Dedicated SV copying code in place of Perl_sv_setsv_flags#23202richardleach merged 13 commits intoPerl:bleadfrom
richardleach merged 13 commits intoPerl:bleadfrom
Conversation
bulk88
reviewed
Apr 18, 2025
bulk88
reviewed
Apr 18, 2025
bulk88
reviewed
Apr 18, 2025
bulk88
reviewed
Apr 18, 2025
bulk88
reviewed
Apr 18, 2025
bulk88
reviewed
Apr 18, 2025
bulk88
reviewed
Apr 18, 2025
bulk88
reviewed
Apr 18, 2025
bulk88
reviewed
Apr 18, 2025
bulk88
reviewed
Apr 18, 2025
bulk88
reviewed
Apr 18, 2025
bulk88
reviewed
Apr 18, 2025
bulk88
reviewed
Apr 18, 2025
bulk88
reviewed
Apr 18, 2025
bulk88
reviewed
Apr 18, 2025
bulk88
reviewed
Apr 18, 2025
bulk88
reviewed
Apr 18, 2025
Contributor
|
Cloning is rather unfortunate choice of words, given that it has a very specific meaning in our codebase that is quite different from what this PR is about. Renaming the PR may be helpful. |
c392526 to
91c2b99
Compare
Contributor
Author
|
I've made a lot of changes following earlier comments - thanks for those - and have finally force-pushed. These changes aren't complete. For example:
|
richardleach
commented
May 8, 2025
91c2b99 to
583bbac
Compare
583bbac to
d1e53fd
Compare
d1e53fd to
05d5efa
Compare
05d5efa to
bf95ea0
Compare
Contributor
|
the last commit's message indicates it should be squashed |
bulk88
reviewed
Aug 13, 2025
bulk88
reviewed
Aug 13, 2025
bulk88
reviewed
Aug 13, 2025
bulk88
reviewed
Aug 13, 2025
bulk88
reviewed
Aug 13, 2025
bulk88
reviewed
Aug 13, 2025
131563e to
1197bc1
Compare
Contributor
Author
|
Thanks, I've hopefully addressed those comments and squashed all trailing commits. |
27ffa67 to
dda1c95
Compare
tonycoz
reviewed
Aug 14, 2025
Perl_newSVsv_flags_NN creates a fresh SV that contains the values of its
source SV argument. It's like calling `new_SV(dsv)` followed by
`sv_setsv_flags(dsv, ssv, flags`, but is optimized for a brand new
destination SV and the most common code paths.
The intended initial users for this new function were:
* Perl_sv_mortalcopy_flags (still in sv.c)
* Perl_newSVsv_flags (now a simple function in sv_inline.h)
Perl_newSVsv_flags_NN prioritises the following hot cases:
* SVt_IV containing an IV
* SVt_IV containing an RV
* SVt_NV containing an NV
* SVt_PV containing a PV
It will then check for:
* SVt_NULL
* SVt_IV containing a UV
* SVt_LAST
The helper function S_newSVsv_flags_NN_PVxx is called for everything else.
It will use Perl_sv_setsv_flags as a fallback for rare or tricky cases.
S_newSVsv_flags_NN_POK is a dedicated helper for string swipe/COW/copy
logic and is called from both Perl_newSVsv_flags_NN and
S_newSVsv_flags_NN_PVxx.
With these changes compared with the previous commit:
* `perl -e 'for (1..100_000_0) { my $x = { (1) x 1000 }; }'` runs about 20% faster
* `perl -e 'for (1..100_000_0) { my $x = { ("Perl") x 250 }' runs about 40% faster
* `perl -e 'for (1..100_000_0) { my $x = { a => 1, b => 2, c => 3, d => 4, e => 5 }; }'`
is a touch faster, but within the margin for error
* `perl -e 'for (1..100_000_0) { my $x = { a => "Perl", b => "Perl", c => "Perl", d => "Perl", e => "Perl" } ; }'`
runs about 17% faster
Perl_newSVsv_flags has become just a stub around Perl_newSVsv_flags_NN. For callers where the source SV* is NULL, not having to call a function in sv.c to immediately return is very desirable.
Besides using the just-introduced faster path for SV copying, this allows the check for SV_GMAGIC to be pushed into the called function without having to worry about SV leaks. Two additional micro-optimizations are also in this commit: * A pointer to xav_fill is cached for use in the loop. This can be used directly to update AvFILLp(av), rather than having to get there from av's SV* each time. * The value of the loop iterator, i, is directly written into xav_fill, rather than getting the value in that slot, incrementing it (to get the same value as i), and writing it back.
dda1c95 to
703a3e0
Compare
tonycoz
approved these changes
Aug 18, 2025
Contributor
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Perl_sv_setsv_flagsis the heavyweight function for assigning the value(s) ofa source SV to a destination SV. It contains many branches for preparing the
destination SV prior to assignment. However:
This set of commits:
Perl_sv_setsv_flagsinto a macro.Perl_sv_freshcopy_flagsand two static helper functions.Perl_newSVsv_flagsandPerl_sv_mortalcopy_flagsto use them.should use
Perl_newSVsv_flagsorPerl_sv_mortalcopy_flags.Using perl's test harness as a guide:
Perl_newSVsv_flagsand57% of calls to
Perl_sv_mortalcopy_flags.SVt_PV/SVp_POKcode handles 32% of calls toPerl_newSVsv_flagsand 36% of calls toPerl_sv_mortalcopy_flags.S_sv_freshcopy_flagscode handles 95% of the remainder inPerl_newSVsv_flagsand 91% of the remainder in toPerl_sv_mortalcopy_flags.With these changes compared with a build of blead:
perl -e 'for (1..100_000) { my $x = [ (1) x 1000 ]; }'runs 10% fasterperl -e 'for (1..100_000) { my $x = [ ("Perl") x 250 ]; }'runs 45% faster